package com.zp.imagecompresspractice.Compressor;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

/**
 * Created by izp on 2017/6/5.
 */

public class FileUtil {
    static final String FILES_PATH = "Compressor";
    private static final int EOF = -1;
    private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

    private FileUtil() {

    }

    /**
     * @param context 上下文
     * @param uri  根据contentProvider的url
     * @return  返回生成的File对象
     * @throws IOException
     */
    public static File from(Context context, Uri uri) throws IOException {
        //        从contentProvider路径生成输入流
        InputStream inputStream = context.getContentResolver().openInputStream(uri);
//      通过uri获取文件名称
        String fileName = getFileName(context, uri);
//       获取文件名极其扩展名
        String[] splitName = splitFileName(fileName);
        File tempFile = File.createTempFile(splitName[0], splitName[1]);
        tempFile = rename(tempFile, fileName);
        tempFile.deleteOnExit();
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(tempFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream != null) {
            copy(inputStream, out);
            inputStream.close();
        }

        if (out != null) {
            out.close();
        }
        return tempFile;
    }
    /**
     * @param context 上下文
     * @param uri  根据contentProvider的url
     * @return  返回生成的File对象
     * @throws IOException
     */
    public static File from(Context context, String path) throws IOException {
        //        从contentProvider路径生成输入流
//        InputStream inputStream = context.getContentResolver().openInputStream(uri);
        FileInputStream inputStream = context.openFileInput(path);
//      通过uri获取文件名称
//        /storage/emulated/0/DCIM/Screenshots/Screenshot_20170608-173415.png
        String fileName = getFileName(context, path);
//       获取文件名极其扩展名
        String[] splitName = splitFileName(fileName);
        File tempFile = File.createTempFile(splitName[0], splitName[1]);
        tempFile = rename(tempFile, fileName);
        tempFile.deleteOnExit();
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(tempFile);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream != null) {
            copy(inputStream, out);
            inputStream.close();
        }

        if (out != null) {
            out.close();
        }
        return tempFile;
    }

    /**
     * 分割文件名
     * @param fileName 传入文件名
     * @return
     */
    static String[] splitFileName(String fileName) {
        String name = fileName;
//        扩展名称
        String extension = "";
//        获取文件最后一个点，来获取扩展名
        int i = fileName.lastIndexOf(".");
        if (i != -1) {
//            获取文件名
            name = fileName.substring(0, i);
//            获取扩展名
            extension = fileName.substring(i);
        }

        return new String[]{name, extension};
    }

    /**
     * @param context 上下文
     * @param uri 这个应该是根据contentProvider来获取文件名称
     * @return 返回文件名
     */
    static String getFileName(Context context, Uri uri) {
        String result = null;
//        判断uri类型uri.getScheme()
        if (uri.getScheme().equals("content")) {
            Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
//            通过uri查找文件
            try {
//                如果游标不为空，且游标可以移动到第一个
                if (cursor != null && cursor.moveToFirst()) {
//                   通过游标获取储存名字的那一行的索引，并根据索引获取到文件名
                    result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
//                关闭游标
                if (cursor != null) {
                    cursor.close();
                }
            }
        }
//        如果经过上面的运行，result仍然为null，有可能是uri类型问题，也有可能是try中的问题。
        if (result == null) {
//            如果result经过上面运行仍然是空，那么从uri上获取绝对路径
            result = uri.getPath();
//            获取绝对路径中最后一个分隔符
            int cut = result.lastIndexOf(File.separator);
            if (cut != -1) {
//                如果最后一个分隔符存在，那么就从最后一个分隔符+1开始截取之后所有的string
                result = result.substring(cut + 1);
            }
        }
        return result;
    }
    /**
     * @param context 上下文
     * @param path 这个应该是根据contentProvider来获取文件名称
     * @return 返回文件名
     */
    static String getFileName(Context context, String path) {
        String result = path;
//        如果经过上面的运行，result仍然为null，有可能是uri类型问题，也有可能是try中的问题。

//            如果result经过上面运行仍然是空，那么从uri上获取绝对路径
//            获取绝对路径中最后一个分隔符
        int cut = result.lastIndexOf(File.separator);
        if (cut != -1) {
//                如果最后一个分隔符存在，那么就从最后一个分隔符+1开始截取之后所有的string
            result = result.substring(cut + 1);
        }
        return result;
    }

    static String getRealPathFromURI(Context context, Uri contentUri) {
        Cursor cursor = context.getContentResolver().query(contentUri, null, null, null, null);
        if (cursor == null) {
            return contentUri.getPath();
        } else {
            cursor.moveToFirst();
            int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
            String realPath = cursor.getString(index);
            cursor.close();
            return realPath;
        }
    }

    static File rename(File file, String newName) {
        File newFile = new File(file.getParent(), newName);
        if (!newFile.equals(file)) {
            if (newFile.exists()) {
                if (newFile.delete()) {
                    Log.d("FileUtil", "Delete old " + newName + " file");
                }
            }
            if (file.renameTo(newFile)) {
                Log.d("FileUtil", "Rename file to " + newName);
            }
        }
        return newFile;
    }

    static int copy(InputStream input, OutputStream output) throws IOException {
        long count = copyLarge(input, output);
        if (count > Integer.MAX_VALUE) {
            return -1;
        }
        return (int) count;
    }

    static long copyLarge(InputStream input, OutputStream output)
            throws IOException {
        return copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]);
    }

    static long copyLarge(InputStream input, OutputStream output, byte[] buffer)
            throws IOException {
        long count = 0;
        int n;
        while (EOF != (n = input.read(buffer))) {
            output.write(buffer, 0, n);
            count += n;
        }
        return count;
    }
}
